home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Tool Chest / QuickDraw GX / QuickDraw GX Info / QuickDraw GX Interfaces / Interfaces & Libraries / graphics libraries / qd library.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-30  |  12.9 KB  |  390 lines  |  [TEXT/MPS ]

  1. /* graphics libraries:  
  2.     quickdraw conversion library
  3.     by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  4.     Copyright 1987 - 1991 Apple Computer, Inc.  All rights reserved.    */
  5.  
  6.  
  7.     #include <Errors.h>
  8.     #include <GestaltEqu.h>
  9.     #include <Quickdraw.h>
  10.     #include <Memory.h>
  11.     #include <Resources.h>
  12.  
  13. #include "graphics libraries.h"
  14. #include "offscreen library.h"
  15. #include "qd library.h"
  16.  
  17.  
  18. gxRectangle *ShortRectToFixed(const Rect *shortRect, gxRectangle *fixedRect)
  19. {
  20.     register Fixed *coord;
  21.     
  22.     NilParamReturnNil(shortRect);
  23.     NilParamReturnNil(fixedRect);
  24.     coord = (Fixed *) fixedRect;
  25.     *coord++ = IntToFixed(shortRect->left);
  26.     *coord++ = IntToFixed(shortRect->top);
  27.     *coord++ = IntToFixed(shortRect->right);
  28.     *coord    = IntToFixed(shortRect->bottom);
  29.     return fixedRect;
  30. }
  31.  
  32.  
  33. Rect *FixedRectToShort(const gxRectangle *fixedRect, Rect *shortRect)
  34. {
  35.     register short *coord;
  36.     
  37.     NilParamReturnNil(shortRect);
  38.     NilParamReturnNil(fixedRect);
  39.     coord = (short *) shortRect;
  40.     *coord++ = FixedRound(fixedRect->top);
  41.     *coord++ = FixedRound(fixedRect->left);
  42.     *coord++ = FixedRound(fixedRect->bottom);
  43.     *coord     = FixedRound(fixedRect->right);
  44.     return shortRect;
  45. }
  46.  
  47. gxPoint *ShortPointToFixed(const Point *shortPoint, gxPoint *fixedPoint)
  48. {
  49.     NilParamReturnNil(shortPoint);
  50.     NilParamReturnNil(fixedPoint);
  51.     fixedPoint->x = IntToFixed(shortPoint->h);
  52.     fixedPoint->y = IntToFixed(shortPoint->v);
  53.     return fixedPoint;
  54. }
  55.  
  56.  
  57. Point *FixedPointToShort(const gxPoint *fixedPoint, Point *shortPoint)
  58. {   
  59.     NilParamReturnNil(shortPoint);
  60.     NilParamReturnNil(fixedPoint);
  61.     shortPoint->h = FixedRound(fixedPoint->x);
  62.     shortPoint->v = FixedRound(fixedPoint->y);
  63.     return shortPoint;
  64. }
  65.  
  66. static gxColorSet CTabPtrToColorSet(const CTabPtr qdColors)
  67. {
  68.     gxColorSet gnuSet;
  69.  
  70.     NilParamReturnNil(qdColors);
  71.     {   gxSetColor *tempColors, *colorPtr;
  72.         unsigned short *qdSpec;
  73.         short count, size;
  74.  
  75.         size = qdColors->ctSize + 1;
  76.         tempColors = (gxSetColor *) NewPtr(size * sizeof(gxSetColor));
  77.         NilParamReturnNil(tempColors);
  78.         count = size;
  79.         colorPtr = tempColors;
  80.         qdSpec = (unsigned short *) &qdColors->ctTable;
  81.         while (--count >= 0)
  82.         {
  83.             ++qdSpec;
  84.             colorPtr->rgb.red = *qdSpec++;
  85.             colorPtr->rgb.green = *qdSpec++;
  86.             colorPtr->rgb.blue = *qdSpec++;
  87.             ++colorPtr;
  88.         }
  89.         gnuSet = GXNewColorSet(gxRGBSpace, size, tempColors);
  90.         DisposePtr((char *) tempColors);
  91.     }
  92.     return gnuSet;
  93. }
  94.  
  95.  
  96. gxColorSet CTableToColorSet(const CTabHandle qdColors)
  97. {   char flags;
  98.     gxColorSet gnuSet;
  99.  
  100.     NilParamReturnNil(qdColors);
  101.     flags = HGetState((char**)qdColors);
  102.     HLock((char**)qdColors);
  103.     gnuSet = CTabPtrToColorSet(*qdColors);
  104.     HSetState((char**)qdColors,flags);
  105.     return gnuSet;
  106. }
  107.  
  108.  
  109. CTabHandle ColorSetToCTable(const gxColorSet set)
  110. {
  111.     long i,n,numbertocopy;
  112.     CTabHandle mycolortable;
  113.     gxSetColor * mycolorlist;
  114.     gxColorSpace setSpace;
  115.     
  116.     NilColorSetReturnNil(set);
  117.     n = GXGetColorSet(set, nil, nil);
  118.     if (n < 4) numbertocopy = 2;
  119.     else if (n < 16) numbertocopy = 4;
  120.     else if (n < 256) numbertocopy = 16;
  121.     else numbertocopy = 256;
  122.     mycolorlist = (gxSetColor *)NewPtr(sizeof(gxSetColor)*numbertocopy);
  123.     NilParamReturnNil(mycolorlist);
  124.     mycolortable = (CTabHandle)NewHandle(sizeof(ColorTable)+numbertocopy*sizeof(ColorSpec));
  125.     NilParamReturnNil(mycolortable);
  126.     GXGetColorSet(set, &setSpace, mycolorlist );
  127.     (*mycolortable)->ctSeed = 0;
  128.     (*mycolortable)->ctFlags = 0;
  129.     (*mycolortable)->ctSize = numbertocopy-1;
  130.     for (i = 0; i < numbertocopy; i++) 
  131.     {   gxColor tempcolor;
  132.     
  133.         tempcolor.element.rgba = mycolorlist[i].rgba;
  134.         tempcolor.space = setSpace;
  135.         tempcolor.profile = nil;
  136.         if (setSpace != gxRGBSpace) GXConvertColor(&tempcolor,gxRGBSpace, nil, nil);
  137.         (*mycolortable)->ctTable[i].value = 0;
  138.         (*mycolortable)->ctTable[i].rgb.red = tempcolor.element.rgb.red;
  139.         (*mycolortable)->ctTable[i].rgb.green = tempcolor.element.rgb.green;
  140.         (*mycolortable)->ctTable[i].rgb.blue = tempcolor.element.rgb.blue;
  141.     }
  142.     return mycolortable;
  143. }
  144.  
  145.  
  146. /*** WARNING - this proc. should only be used with a rowBytes that is a multiple of four */
  147. /*** We should rev this to no longer have this restriction (by copying the gxBitmap, for example) */
  148. gxBitmap *ConvertFromQDBitmap(const BitMap *qdBits, gxBitmap *newBits)
  149. {
  150.     NilParamReturnNil(qdBits);
  151.     NilParamReturnNil(newBits);
  152.     newBits->image = qdBits->baseAddr;
  153.     newBits->rowBytes = qdBits->rowBytes;
  154.     newBits->width = qdBits->bounds.right - qdBits->bounds.left;
  155.     newBits->height = qdBits->bounds.bottom - qdBits->bounds.top;
  156.     newBits->pixelSize = 1;
  157.     newBits->space = gxIndexedSpace;
  158.     newBits->set = nil;
  159.     newBits->profile = nil;
  160.     return newBits;
  161. }
  162.  
  163. BitMap *ConvertToQDBitmap(const gxBitmap *newBits, BitMap *qdBits)
  164. {
  165.     NilParamReturnNil(qdBits);
  166.     NilParamReturnNil(newBits);
  167.     qdBits->baseAddr = newBits->image;
  168.     qdBits->rowBytes = newBits->rowBytes;
  169.     SetRect(&qdBits->bounds, 0, 0, newBits->width, newBits->height);
  170.     return qdBits;
  171. }
  172.  
  173. gxShape BitMapToShape(const BitMap *srcBits)
  174. {
  175.     gxBitmap newBits;
  176.     gxShape bitmapShape;
  177.  
  178.     NilParamReturnNil(srcBits);
  179.     bitmapShape = GXNewBitmap(ConvertFromQDBitmap(srcBits, &newBits), nil);
  180.     return bitmapShape;
  181. }
  182.  
  183. gxShape PixMapToShape(const PixMapHandle pmHandle)
  184. {
  185.     gxShape bitsShape;        /* the result gxShape */
  186.     PixMap pixmaprecord;    /* the header is read into here if we're using partial resources */
  187.     PixMap *pixmap;     /* points either into the resource or to the above record */
  188.     gxBitmap srcBits;
  189.     gxBitmap dstBits;
  190.     register short srcRowBytes;
  191.     char savedHandleFlags;      /* so we can restore the handle state after we lock it */
  192.     boolean partialReads = false;   /* are we using partial resources to read a bit at a time? */
  193.     
  194.     NilParamReturnNil(pmHandle);
  195.     if (*pmHandle == nil) {
  196.         long systemVersion; /* filled out by Gestalt */
  197.         OSErr err;
  198.         
  199.         /* The resource isn't loaded.  Try to read it in all at once, since that's quite a bit faster,
  200.           * but if that isn't possible because there isn't enough memory, use the partial resource
  201.           * manager to read it in a bit at a time.
  202.           */
  203.         LoadResource((Handle) pmHandle);
  204.         err = ResError();
  205.         if (err == memFullErr && Gestalt(gestaltSystemVersion, &systemVersion) == noErr && systemVersion >= 1792) {
  206.             partialReads = true;
  207.             ReadPartialResource((Handle) pmHandle, 0, (Ptr) (pixmap = &pixmaprecord), sizeof(pixmaprecord));
  208.             if ((err = ResError()) != 0) goto returnResError;
  209.         } else if (err) {
  210.         returnResError:
  211.                 GXPostGraphicsError(err);
  212.                 return nil;
  213.         } else {
  214.             (*pmHandle)->pmTable = nil;
  215.             (*pmHandle)->baseAddr = nil;
  216.         }
  217.     }
  218.  
  219.     
  220.     savedHandleFlags = HGetState((Handle) pmHandle);
  221.     HLock((Handle) pmHandle);
  222.     if (partialReads == false)
  223.         pixmap = *pmHandle;
  224.     dstBits.space = gxIndexedSpace;
  225.     dstBits.set = nil;
  226.     dstBits.profile = nil;
  227.     dstBits.pixelSize = pixmap->pixelSize;
  228.     dstBits.width = pixmap->bounds.right - pixmap->bounds.left;
  229.     dstBits.height = pixmap->bounds.bottom - pixmap->bounds.top;
  230.     srcRowBytes = pixmap->rowBytes & 0x3FFF;
  231.     dstBits.rowBytes = srcRowBytes;
  232.     if (dstBits.pixelSize <= 8) {
  233.         CTabHandle ctHandle;
  234.         
  235.         if (partialReads) {
  236.             long resourceOffset = sizeof(PixMap) + srcRowBytes * dstBits.height;
  237.             ColorTable cTable;
  238.             CTabPtr ctPtr;
  239.             long size;
  240.             
  241.             ReadPartialResource((Handle) pmHandle, resourceOffset, (Ptr) &cTable, sizeof(cTable));
  242.             size = sizeof(ColorTable) - sizeof(CSpecArray) + cTable.ctSize * sizeof(CSpecArray);
  243.             ctPtr = (CTabPtr) NewPtr(size);
  244.             IfDebug(ctPtr == nil, "\pcouldn't allocate CTabPtr");
  245.             ReadPartialResource((Handle) pmHandle, resourceOffset, (Ptr) ctPtr, size);
  246.             dstBits.set = CTabPtrToColorSet(ctPtr);
  247.             DisposePtr((Ptr) ctPtr);
  248.         } else if ((ctHandle = pixmap->pmTable) != nil)
  249.             dstBits.set = CTableToColorSet(ctHandle);
  250.         else
  251.             dstBits.set = CTabPtrToColorSet((CTabPtr) ((char *) pixmap + sizeof(PixMap) + srcRowBytes * dstBits.height));
  252.         dstBits.space = gxIndexedSpace;
  253.     } else if (dstBits.pixelSize == 16)
  254.         dstBits.space = gxRGB16Space;
  255.     else
  256.         dstBits.space = gxRGB32Space;
  257.     {
  258.         long resourceOffset;
  259.         gxShape pixShape;
  260.         short scans;
  261.         gxLongRectangle bounds;
  262.         
  263.         /*  Decide how many scan lines to copy at once.  If we use smaller chunks than the whole image,
  264.             we never have to load the whole resource into memory, and the graphics system can offload
  265.             pieces of it as they're written.  Otherwise, the whole resource and the whole destination gxShape
  266.             must be in memory at once.  Enough lines to come in just under 32K seems like a reasonable number.
  267.         */
  268.         dstBits.image = nil;
  269.         srcBits = dstBits;
  270.         if (srcRowBytes & 3) {  /* make it a long multiple */
  271.             dstBits.rowBytes = srcRowBytes + 3 & ~3;
  272.             scans = 1;
  273.         } else if (partialReads)
  274.             scans = 1;
  275.         else {
  276.             scans = 32768 / srcRowBytes;
  277.             if (scans == 0)
  278.                 scans = 1;
  279.         }
  280.         if (scans > dstBits.height)
  281.             scans = dstBits.height;
  282.         srcBits.height = scans;
  283.         if (partialReads) {
  284.             resourceOffset = sizeof(PixMap);
  285.             srcBits.image = NewPtr(srcBits.rowBytes);
  286.             IfDebug(srcBits.image == nil, "\pcouldn't allocate rowBytes");
  287.         } else if ((srcBits.image = pixmap->baseAddr) == nil)
  288.             srcBits.image = (char *) pixmap + sizeof(PixMap);
  289.         bitsShape = GXNewBitmap(&dstBits, nil);
  290.         pixShape = GXNewBitmap(&dstBits, nil);
  291.         bounds.left = bounds.top = 0;
  292.         bounds.right = srcBits.width;
  293.         bounds.bottom = scans;
  294.         while (bounds.top < dstBits.height) {
  295.             if (partialReads) {
  296.                 ReadPartialResource((Handle) pmHandle, resourceOffset, srcBits.image, srcBits.rowBytes);
  297.                 resourceOffset += srcBits.rowBytes;
  298.             }
  299.             GXSetBitmap(pixShape, &srcBits, nil);
  300.             GXSetBitmapParts(bitsShape, &bounds, pixShape);
  301.             bounds.top += scans;
  302.             bounds.bottom += scans;
  303.             if (bounds.bottom > dstBits.height)
  304.                 bounds.bottom = dstBits.height;
  305.             if (partialReads == false)
  306.                 srcBits.image += scans * srcBits.rowBytes;
  307.         }
  308.         if (partialReads)
  309.             DisposePtr(srcBits.image);
  310.         GXDisposeShape(pixShape);
  311.     }
  312.     HSetState((Handle) pmHandle, savedHandleFlags);
  313.     if (dstBits.set)
  314.         GXDisposeColorSet(dstBits.set);
  315.     return bitsShape;
  316. }
  317.  
  318.  
  319. gxShape GetPixMapShape(short resourceID)
  320. {
  321.     PixMapHandle pmHandle;
  322.     
  323.     SetResLoad(false);
  324.     pmHandle = (PixMapHandle) GetResource('pxmp', resourceID);
  325.     SetResLoad(true);
  326.     if (pmHandle) {
  327.         gxShape dest;
  328.         
  329.         dest = PixMapToShape(pmHandle);
  330.         ReleaseResource((char**)pmHandle);
  331.         return dest;
  332.     } else
  333.         return nil;
  334. }
  335.  
  336. #define kColorSpecSize 8
  337.  
  338. gxShape CICNToMask(CIconHandle iconH)
  339. {
  340.     CIconPtr iconP;
  341.     
  342.     NilParamReturnNil(iconH);
  343.     iconP = *iconH;
  344.     iconP->iconMask.baseAddr = (Ptr) &iconP->iconMaskData;
  345.     return BitMapToShape(&iconP->iconMask);
  346. }
  347.  
  348. gxShape CICNToShape(CIconHandle iconH)
  349. {
  350.     NilParamReturnNil(iconH);
  351.     {   gxShape result = nil;
  352.         CIconPtr iconP = *iconH;
  353.         long height = iconP->iconPMap.bounds.bottom - iconP->iconPMap.bounds.top;
  354.         ColorTable* clut =  (ColorTable*) (((char*)&iconP->iconMaskData) 
  355.                                                 + iconP->iconBMap.rowBytes*height
  356.                                                 + iconP->iconMask.rowBytes*height);
  357.         long clutSize = 8+((clut->ctSize+1)*kColorSpecSize);
  358.     
  359.         PtrToHand((Ptr) clut, (Handle *) &iconP->iconPMap.pmTable, clutSize);
  360.         iconP->iconPMap.baseAddr = (((char*)clut) + clutSize);
  361.         result = PixMapToShape((PixMapHandle) iconH);
  362.         DisposHandle((Handle) iconP->iconPMap.pmTable);
  363.         return result;
  364.     }
  365. }
  366.     
  367. gxShape GetCICNMask(long resourceID)
  368. {
  369.     gxShape result = nil;
  370.     CIconHandle iconH = (CIconHandle) GetResource('cicn', resourceID);
  371.     
  372.     if (iconH) {
  373.         result = CICNToMask(iconH);
  374.         ReleaseResource((Handle)iconH);
  375.     }
  376.     return result;
  377. }
  378.     
  379. gxShape GetCICNShape(long resourceID)
  380. {
  381.     gxShape result = nil;
  382.     CIconHandle iconH = (CIconHandle) GetResource('cicn', resourceID);
  383.     
  384.     if (iconH) {
  385.         result = CICNToShape(iconH);
  386.         ReleaseResource((Handle)iconH);
  387.     }       
  388.     return result;
  389. }
  390.